package com.hunter.lucene.util.search;

import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.search.BooleanClause.Occur;

/**
 * Query  的工具的类。
 * @author bastengao
 *
 */
public class Queries {
	/**
	 * 最基本的搜索，搜索单个词
	 * 
	 * @param fieldName
	 * @param keyword
	 * @return
	 */
	public static Query termQuery(String fieldName, String keyword) {
		return new TermQuery(new Term(fieldName, keyword));
	}

	/**
	 * 范围搜索，可以搜索某个区间
	 * 
	 * @param fieldName
	 * @param lowerTerm
	 * @param upperTerm
	 * @param includeLower
	 * @param includeUpper
	 * @return
	 */
	public static Query termRangeQuery(String fieldName, String lowerTerm,
			String upperTerm, boolean includeLower, boolean includeUpper) {
		return new TermRangeQuery(fieldName, lowerTerm, upperTerm,
				includeLower, includeUpper);
	}

	/**
	 * 前缀搜索。如 app ，就会匹配上 application 。类似于 app*。
	 * @param fieldName
	 * @param prefix
	 * @return
	 */
	public static Query prefixQuery(String fieldName, String prefix) {
		Term prefixTerm = new Term(fieldName, prefix);
		return new PrefixQuery(prefixTerm);
	}

	/**
	 * 把这些Query 重新组织为 一个新的 Query，他们的关系都是或的关系
	 * 
	 * @param queries
	 * @return
	 */
	public static Query orQuery(Query[] queries) {
		BooleanQuery query = new BooleanQuery();
		for (Query q : queries) {
			query.add(q, Occur.SHOULD);
		}
		return query;
	}

	/**
	 * 把这些Query 重新组织为 一个新的 Query，他们的关系都是且的关系
	 * 
	 * @param queries
	 * @return
	 */
	public static Query andQuery(Query[] queries) {
		BooleanQuery query = new BooleanQuery();
		for (Query q : queries) {
			query.add(q, Occur.MUST);
		}
		return query;
	}

	/**
	 * 把这些Query 重新组织为 一个新的 Query，他们的关系需要根据需要自定义
	 * 
	 * @param queries
	 * @param occurs
	 * @return
	 */
	public static Query groupQuery(Query[] queries, Occur[] occurs) {
		if (queries.length != occurs.length) {
			throw new IllegalArgumentException(
					"queries length must be the same with occurs length.");
		}
		BooleanQuery query = new BooleanQuery();
		int length = queries.length;
		for (int i = 0; i < length; i++) {
			query.add(queries[i], occurs[i]);
		}
		return query;
	}
}
